﻿/**
 * Name             :   UserPreference 
 * Namespace        :   MetroTemplate.Model
 * Base Classe      :   IBaseClass
 * Type             :   Classe
 * Author           :   Hamza SAII
 * Creation         :   01/10/2014
 * Updated          :   01/10/2014
 * Licence          :   Public
 * Comment          :   NONE
 * */

namespace MetroTemplate.Model
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using Interfaces;
    using System.Reflection;
    using System.Drawing;

    /// <summary>
    /// Représente la liste des paramètres qui correspondent à l'utilisateur courant
    /// </summary>
    public class UserPreference : IBaseClass
    {

        #region Constructeurs
        /// <summary>
        /// Constructeur par défaut
        /// </summary>
        /// <remarks>Permet de charger / enregistrer les paramètres par défaut de l'application</remarks>
        public UserPreference()
        {
            Load();
        }

        #endregion

#region Propreties and Fields
        private string _Font;
        private string _FontSize;
        private string _Theme;
        private string _LabelBackColor;
        private string _BackGround;

        /// <summary>
        /// Identifie les paramètres de regsitre à utiliser
        /// </summary>
        private Microsoft.Win32.RegistryKey CurrentReg { get; set; }
        private Microsoft.Win32.RegistryKey ClasseKey { get; set; }
        private Microsoft.Win32.RegistryKey AppKey { get; set; }

        /// <summary>
        /// Le police des contrôles graphiques
        /// </summary>
        public string Font {
            get
            {
                return _Font;
            }
            set
            {
                RaiseChangingEvent("Font");
                if (value == null)
                    value = "";

                if (_Font != value)
                {
                    SetPropertyValue("font", value);
                    _Font = value;
                }
                RaiseChangedEvent("Font");
            }
        }

        /// <summary>
        /// La taille du police utilisé
        /// </summary>
        public int FontSize
        {
            get
            {
                return int.Parse(_FontSize);
            }
            set
            {
                RaiseChangingEvent("FontSize");
                string newValue = value + "";
                if (_FontSize != newValue)
                {
                    SetPropertyValue("fontsize", newValue);
                    _FontSize = newValue;
                }
                RaiseChangedEvent("FontSize");
                
            }
        }
        
        /// <summary>
        /// Le thème de l'utilisateur en cours
        /// </summary>
        public string Theme
        {
            get
            {
                return _Theme;
            }
            set
            {
                RaiseChangingEvent("Theme");
                if (value == null)
                    value = "";

                if (_Theme != value)
                {
                    SetPropertyValue("theme", value);
                    _Theme = value;
                }
                RaiseChangedEvent("Theme");
            }
        }

        /// <summary>
        /// L'arrière plan des label
        /// </summary>
        public Color LabelBackColor
        {
            get
            {
                return Color.FromName(_LabelBackColor);
            }
            set
            {
                string color = value.Name;
                RaiseChangingEvent("LabelBackColor");

                if (_Theme != color)
                {
                    SetPropertyValue("labelbackcolor", color);
                    _Theme = color;
                }
                RaiseChangedEvent("LabelBackColor");
            }
        }

        /// <summary>
        /// L'arrière plan de l'interface de l'application
        /// </summary>
        /// <remarks>Soit null soit base 64 string</remarks>
        public string BackGround
        {
            get
            {
                return _BackGround;
            }
            set
            {
                RaiseChangingEvent("BackGround");
                if (value == null)
                    value = "";

                if (_BackGround != value)
                {
                    SetPropertyValue("background", value);
                    _BackGround = value;
                }
                RaiseChangedEvent("BackGround");
            }
        }
#endregion

#region Methods
        private void SetPropertyValue(string name,string value)
        {

            //On initialise les paramètres du registre
            CurrentReg = Microsoft.Win32.Registry.CurrentUser;

            string path = "Software\\MetroApp\\";


            //Naviguer vers le dossier de l'application
            AppKey = CurrentReg.OpenSubKey(path, true);
            if (AppKey == null)
            {
                CurrentReg.CreateSubKey(path);
                AppKey = CurrentReg.OpenSubKey(path, true);
            }

            //Naviguer au classe name
            ClasseKey = AppKey.OpenSubKey("UserPreference", true);
            if (ClasseKey == null)
            {
                AppKey.CreateSubKey("UserPreference");
                ClasseKey = AppKey.OpenSubKey("UserPreference", true);
            }

            ClasseKey.SetValue(name, value);
           
            ClasseKey.Close();
            AppKey.Close();
            CurrentReg.Close();
        }

        /// <summary>
        /// Permet de charger la liste des paramètres
        /// </summary>
        /// <returns></returns>
        private void Load()
        {
            //On cherche les propriétés
            PropertyInfo[] propertys = this.GetType().GetProperties();

            // si on a pas de propertys on quitte la fonction
            if (propertys == null)
                return;

            //On initialise les paramètres du registre
            CurrentReg = Microsoft.Win32.Registry.CurrentUser;

            string path = "Software\\MetroApp\\";


            //Naviguer vers le dossier de l'application
            AppKey = CurrentReg.OpenSubKey(path, true);
            if (AppKey == null)
            {
                CurrentReg.CreateSubKey(path);
                AppKey = CurrentReg.OpenSubKey(path, true);
            }

            //Naviguer au classe name
            ClasseKey = AppKey.OpenSubKey("UserPreference", true);
            if (ClasseKey == null)
            {
                AppKey.CreateSubKey("UserPreference");
                ClasseKey = AppKey.OpenSubKey("UserPreference", true);
            }

            // On boucle sur la liste des propertys
            foreach (PropertyInfo p in propertys)
            {
                string paramValue = "";
                if (ClasseKey.GetValue(p.Name.ToLower()) != null)
                    paramValue = ClasseKey.GetValue(p.Name.ToLower()).ToString();
                p.SetValue(this, paramValue, null);
            }

            ClasseKey.Close();
            AppKey.Close();
            CurrentReg.Close();
        }

        /// <summary>
        /// Permet de relacher les ressources utilisée par l'objet
        /// </summary>
        public void Dispose()
        {
            // Initialiser les paramètres
            _Font = null;
            _FontSize = null;
            _Theme = null;
            _LabelBackColor = null;
            _BackGround = null;

            //Initialiser les entrées registry
            if (ClasseKey != null)
                ClasseKey.Dispose();
            if (AppKey != null)
                AppKey.Dispose();

            if (AppKey != null)
                AppKey.Dispose();

            if (CurrentReg != null)
                CurrentReg.Dispose();
            
            // Garbage Collector
            GC.Collect();
        }

        /// <summary>
        /// Permet de créer une copie de la classe en cours
        /// </summary>
        /// <remarks>Les paramètres de l'utilisateurs sont uniques et donc 
        /// la copie va donner la même réference du classe</remarks>
        /// <returns>UserPreference Copie de la classe en cours</returns>
        public object Clone()
        {
            return this;
        }
#endregion
        
#region Events
        /// <summary>
        /// Permet de déclancher l'évenement PropertyChanged
        /// </summary>
        /// <param name="paramname">Le nom de la propriété modifiée</param>
        private void RaiseChangedEvent(string paramname)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(paramname));
            }
        }

        /// <summary>
        /// Permet de déclanché l'évenement PropertyChanging
        /// </summary>
        /// <param name="paramname">Le nom de la propriété en cours de changement</param>
        private void RaiseChangingEvent(string paramname)
        {
            if (PropertyChanging != null)
            {
                PropertyChanging(null, new System.ComponentModel.PropertyChangingEventArgs(paramname));
            }
        }

        public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;

        public event System.ComponentModel.PropertyChangingEventHandler PropertyChanging;
#endregion

    }
}
